package com.hmall.item.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.common.domain.PageDTO;
import com.hmall.common.exception.BizIllegalException;
import com.hmall.common.utils.BeanUtils;
import com.hmall.item.domain.dto.ItemDTO;
import com.hmall.item.domain.dto.OrderDetailDTO;
import com.hmall.item.domain.po.Item;
import com.hmall.item.domain.query.ItemPageQuery;
import com.hmall.item.mapper.ItemMapper;
import com.hmall.item.service.IItemService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author itheima
 */
@Service
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item> implements IItemService {

    @Autowired
    private RestHighLevelClient  client;
    @Override
    public void deductStock(List<OrderDetailDTO> items) {
        String sqlStatement = "com.hmall.item.mapper.ItemMapper.updateStock";
        boolean r = false;
        try {
            r = executeBatch(items, (sqlSession, entity) -> sqlSession.update(sqlStatement, entity));
        } catch (Exception e) {
            log.error("更新库存异常", e);
            throw new BizIllegalException("库存不足！");
        }
        if (!r) {
            throw new BizIllegalException("库存不足！");
        }
    }

    @Override
    public List<ItemDTO> queryItemByIds(Collection<Long> ids) {
        return BeanUtils.copyList(listByIds(ids), ItemDTO.class);
    }


    /*
    * es实现查找
    * */

    @Override
    public PageDTO<ItemDTO> search(ItemPageQuery pageQuery) {

        try {
        //创建一个搜索对象
        SearchRequest items = new SearchRequest("items");
        //封装搜索对象，搜索框，
//        items.source().query(
//
//        )

        //bool 包裹所有查询条件
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
            //搜索框：判断有没有数据
        if (StrUtil.isNotBlank(pageQuery.getKey())){
            boolQuery.must(QueryBuilders.matchQuery("name",pageQuery.getKey()));
        }else {
            boolQuery.must(QueryBuilders.matchAllQuery());
        }

        //分类，品牌，价格
            if (StrUtil.isNotBlank(pageQuery.getCategory())){
                boolQuery.filter(QueryBuilders.termQuery("category",pageQuery.getCategory()));
            }
            if (StrUtil.isNotBlank(pageQuery.getBrand())){
                boolQuery.filter(QueryBuilders.termQuery("brand",pageQuery.getBrand()));
            }
            if (pageQuery.getMaxPrice() != null&&  pageQuery.getMinPrice() != null){
                boolQuery.must(QueryBuilders.rangeQuery("price").from(pageQuery.getMinPrice()).to(pageQuery.getMaxPrice()));
            }
        //指定分页参数
            SearchSourceBuilder size = items.source().query(boolQuery).from(pageQuery.getPageNo() - 1 * pageQuery.getPageSize())
                    .size(pageQuery.getPageSize());
            //指定排序方式和字段
            if (StrUtil.isNotBlank(pageQuery.getSortBy())){
            items.source().sort(pageQuery.getSortBy(),pageQuery.getIsAsc() ?  SortOrder.ASC : SortOrder.DESC);
            }

        //高亮字段
            items.source().highlighter(
                    SearchSourceBuilder.highlight().field("name")
                            .requireFieldMatch(false)
            );

        //发送请求，执行搜索

            SearchResponse response = client.search(items, RequestOptions.DEFAULT);

        //解析结果封装dto  解析高亮
            //定义list接收dto
            List<ItemDTO> list = new ArrayList<>();
            long total = response.getHits().getTotalHits().value;
            SearchHit[] hits = response.getHits().getHits();
            for (SearchHit hit : hits){
                ItemDTO itemDTO = JSONUtil.toBean(hit.getSourceAsString(), ItemDTO.class);

                //解析高亮字段
                if (hit.getHighlightFields().containsKey("name")){
                    itemDTO.setName(hit.getHighlightFields().get("name").getFragments()[0].toString());
                }

                list.add(itemDTO);
            }
            //计算总页数
            long pages = total % pageQuery.getPageSize() == 0 ? total / pageQuery.getPageSize() : total / pageQuery.getPageSize() + 1;
            //返回结果

            return new PageDTO<>(total,pages,list);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}











